<template>
  <v-container fluid tag="section">
    <v-row>
      <v-col sm="12" md="3" class="p-0">
        <v-card icon="mdi-clipboard-text" title="机构列表" class="mt-0">
          <v-treeview
            v-model="search.orgId"
            ref="treeEle"
            open-all
            dense
            hoverable
            activatable
            transition
            color="primary"
            :return-object="true"
            :items="orgTreeItems"
            item-key="id"
            item-text="name"
            @update:active="treeOn"
          >
          </v-treeview>
        </v-card>
      </v-col>
      <v-col sm="12" md="9">
        <v-card icon="mdi-clipboard-text" class="px-md-5 py-md-3 pa-xs-0 mt-0">
          <v-card-title>
            <v-row>
              <v-col cols="12" sm="12" md="3">
                <v-text-field
                  v-model="search.account"
                  label="账户"
                ></v-text-field>
              </v-col>
              <v-col cols="12" sm="12" md="3">
                <v-text-field
                  v-model="search.nickName"
                  label="昵称"
                ></v-text-field>
              </v-col>
              <v-col cols="12" sm="12" md="6" class="text-left">
                <v-btn
                  regular
                  color="primary"
                  @click="dataInitialize()"
                  class="mr-2"
                >
                  查 询
                </v-btn>
                <v-btn
                  regular
                  color="warning"
                  @click="clearChanged()"
                  class="ml-2"
                >
                  重 置
                </v-btn>
              </v-col>
            </v-row>
          </v-card-title>
          <v-card-text>
            <v-data-table
              v-model="selectedTableItems"
              :no-data-text="noDataText"
              :show-expand="showExpand"
              :single-expand="singleExpand"
              :show-select="showSelect"
              :single-select="singleSelect"
              :expanded.sync="expanded"
              :dense="dense"
              :headers="headers"
              :items="records"
              :options.sync="options"
              :multi-sort="multiSort"
              :server-items-length="total"
              :loading="loading"
              :item-key="itemKey"
              :loading-text="loadingText"
              :footer-props="footerProps"
              @update:options="dataInitialize()"
            >
              <template v-slot:expanded-item="{ headers, item }">
                <td :colspan="headers.length">
                  用户昵称： {{ item.nickName }}
                </td>
              </template>

              <template v-slot:top>
                <v-toolbar flat>
                  <v-toolbar-title class="d-none d-sm-flex">
                    {{ tableTitle }}
                  </v-toolbar-title>
                  <v-divider
                    class="mx-4 d-none d-sm-flex"
                    inset
                    vertical
                  ></v-divider>
                  <v-spacer></v-spacer>
                  <v-btn color="primary" dark @click="remove(-1)" class="mr-2">
                    批量删除
                  </v-btn>
                  <!-- 添加或修改 -->
                  <v-dialog v-model="dialog" persistent max-width="800px">
                    <template v-slot:activator="{ on, attrs }">
                      <v-btn
                        color="primary"
                        dark
                        class="mb-2"
                        v-bind="attrs"
                        v-on="on"
                      >
                        添加
                      </v-btn>
                    </template>
                    <v-card>
                      <v-card-title class="text-left">
                        <span class="text-h3 font-weight-black text-left">
                          {{ formTitle }}
                        </span>
                      </v-card-title>
                      <v-divider></v-divider>
                      <v-card-text class="pt-4">
                        <v-form ref="form">
                          <v-row>
                            <v-col cols="12" sm="6" md="4" class="pb-0">
                              <div
                                class="
                                  text-h4
                                  font-weight-bold
                                  form-item-required form-item-label
                                "
                              >
                                账号
                              </div>
                              <v-text-field
                                v-model="editedItem.account"
                                :rules="[(v) => !!v || '该项为必填项！']"
                                dense
                                outlined
                              ></v-text-field>
                            </v-col>
                            <v-col cols="12" sm="6" md="4" class="pb-0">
                              <div
                                class="
                                  text-h4
                                  font-weight-bold
                                  form-item-required form-item-label
                                "
                              >
                                姓名
                              </div>
                              <v-text-field
                                v-model="editedItem.name"
                                :rules="[(v) => !!v || '该项为必填项！']"
                                dense
                                outlined
                              ></v-text-field>
                            </v-col>
                            <v-col
                              v-if="editedIndex === -1"
                              cols="12"
                              sm="6"
                              md="4"
                              class="pb-0"
                            >
                              <div
                                class="
                                  text-h4
                                  font-weight-bold
                                  form-item-required form-item-label
                                "
                              >
                                密码
                              </div>
                              <v-text-field
                                v-model="editedItem.password"
                                :rules="[(v) => !!v || '该项为必填项！']"
                                dense
                                type="password"
                                outlined
                              ></v-text-field>
                            </v-col>
                            <v-col cols="12" sm="6" md="4" class="pb-0">
                              <div
                                class="text-h4 font-weight-bold form-item-label"
                              >
                                昵称
                              </div>
                              <v-text-field
                                v-model="editedItem.nickName"
                                dense
                                outlined
                              ></v-text-field>
                            </v-col>
                            <v-col cols="12" sm="6" md="4" class="pb-0">
                              <div
                                class="text-h4 font-weight-bold form-item-label"
                              >
                                生日
                              </div>
                              <v-menu
                                v-model="dateModal"
                                :close-on-content-click="false"
                                :nudge-right="40"
                                transition="scale-transition"
                                offset-y
                                min-width="auto"
                              >
                                <template v-slot:activator="{ on, attrs }">
                                  <v-text-field
                                    v-model="editedItem.birthday"
                                    outlined
                                    dense
                                    readonly
                                    v-bind="attrs"
                                    v-on="on"
                                  ></v-text-field>
                                </template>
                                <v-date-picker
                                  v-model="editedItem.birthday"
                                  dense
                                  locale="zh-cn"
                                  @input="dateModal = false"
                                ></v-date-picker>
                              </v-menu>
                            </v-col>
                            <v-col cols="12" sm="6" md="4" class="pb-0">
                              <div
                                class="
                                  text-h4
                                  font-weight-bold
                                  form-item-required form-item-label
                                "
                              >
                                性别
                              </div>
                              <v-radio-group
                                v-model="editedItem.sex"
                                row
                                dense
                                class="mt-2"
                                :rules="[(v) => !!v || '该项为必填项！']"
                              >
                                <v-radio key="1" value="1" label="男"></v-radio>
                                <v-radio key="2" value="2" label="女"></v-radio>
                              </v-radio-group>
                            </v-col>
                            <v-col cols="12" sm="6" md="4" class="pb-0">
                              <div
                                class="
                                  text-h4
                                  font-weight-bold
                                  form-item-required form-item-label
                                "
                              >
                                邮箱
                              </div>
                              <v-text-field
                                v-model="editedItem.email"
                                :rules="[(v) => !!v || '该项为必填项！']"
                                dense
                                outlined
                              ></v-text-field>
                            </v-col>
                            <v-col cols="12" sm="6" md="4" class="pb-0">
                              <div
                                class="
                                  text-h4
                                  font-weight-bold
                                  form-item-required form-item-label
                                "
                              >
                                手机号
                              </div>
                              <v-text-field
                                v-model="editedItem.phone"
                                :rules="[(v) => !!v || '该项为必填项！']"
                                dense
                                outlined
                              ></v-text-field>
                            </v-col>
                            <v-col cols="12" sm="6" md="4" class="pb-0">
                              <div
                                class="text-h4 font-weight-bold form-item-label"
                              >
                                电话号
                              </div>
                              <v-text-field
                                v-model="editedItem.tel"
                                dense
                                outlined
                              ></v-text-field>
                            </v-col>
                          </v-row>
                        </v-form>
                      </v-card-text>
                      <v-card-actions>
                        <v-spacer></v-spacer>
                        <v-btn text @click="close()" color="darken-1">
                          取消
                        </v-btn>
                        <v-btn text @click="save()" color="primary darken-1">
                          保存
                        </v-btn>
                      </v-card-actions>
                    </v-card>
                  </v-dialog>

                  <!-- 授权角色 -->
                  <v-dialog v-model="rolesDialog" persistent max-width="600px">
                    <v-card>
                      <v-card-title class="text-left">
                        <span class="text-h3 font-weight-black text-left">
                          授权角色
                        </span>
                      </v-card-title>
                      <v-divider></v-divider>
                      <v-card-text class="pt-4">
                        <v-form ref="rolesForm">
                          <v-row>
                            <input
                              type="hidden"
                              v-model="userRoleItem.userId"
                            />
                            <v-col cols="12" class="pb-0">
                              <div
                                class="
                                  text-h4
                                  font-weight-bold
                                  form-item-required form-item-label
                                "
                              >
                                用户角色
                              </div>
                              <v-combobox
                                v-model="userRoleItem.grantRoleIds"
                                :items="dataDicts.roleDicts"
                                multiple
                                chips
                                clearable
                                deletable-chips
                                dense
                                :return-object="true"
                                item-text="name"
                              ></v-combobox>
                            </v-col>
                          </v-row>
                        </v-form>
                      </v-card-text>
                      <v-card-actions>
                        <v-spacer></v-spacer>
                        <v-btn text @click="rolesClose()" color="darken-1">
                          取消
                        </v-btn>
                        <v-btn
                          text
                          @click="rolesSave()"
                          color="primary darken-1"
                        >
                          保存
                        </v-btn>
                      </v-card-actions>
                    </v-card>
                  </v-dialog>

                  <!-- 设置机构 -->
                  <v-dialog
                    v-model="userDataDialog"
                    persistent
                    max-width="600px"
                  >
                    <v-card>
                      <v-card-title class="text-left">
                        <span class="text-h3 font-weight-black text-left">
                          设置机构
                        </span>
                      </v-card-title>
                      <v-divider></v-divider>
                      <v-card-text class="pt-4">
                        <v-form ref="userDataForm">
                          <v-row>
                            <input
                              type="hidden"
                              v-model="userDataItem.userId"
                            />
                            <v-col cols="12" class="pb-0">
                              <div
                                class="
                                  text-h4
                                  font-weight-bold
                                  form-item-required form-item-label
                                "
                              >
                                选择机构
                              </div>
                              <v-treeview
                                v-model="userDataItem.grantOrgIds"
                                ref="userDataTreeEle"
                                selectable
                                dense
                                hoverable
                                :open.sync="userDataOpenItems"
                                :multiple-active="true"
                                :open-on-click="true"
                                transition
                                color="primary"
                                selection-type="independent"
                                :items="userDataTreeItems"
                                :return-object="false"
                                item-key="id"
                                item-text="name"
                              >
                              </v-treeview>
                            </v-col>
                          </v-row>
                        </v-form>
                      </v-card-text>
                      <v-card-actions>
                        <v-spacer></v-spacer>
                        <v-btn text @click="userDataClose()" color="darken-1">
                          取消
                        </v-btn>
                        <v-btn
                          text
                          @click="userDataSave()"
                          color="primary darken-1"
                        >
                          保存
                        </v-btn>
                      </v-card-actions>
                    </v-card>
                  </v-dialog>
                </v-toolbar>
              </template>

              <template v-slot:[`item.sex`]="{ item }">
                {{ item.sex === 1 ? "男" : "女" }}
              </template>

              <template v-slot:[`item.status`]="{ item }">
                {{ statusFilter(item.status) }}
              </template>

              <template v-slot:[`item.actions`]="{ item }">
                <v-menu offset-y rounded="lg">
                  <template v-slot:activator="{ attrs, on, value }">
                    <v-btn
                      color="primary"
                      class="white--text ml-3"
                      v-bind="attrs"
                      v-on="on"
                      small
                    >
                      展开操作
                      <v-icon v-if="value" dark> mdi-chevron-up </v-icon>
                      <v-icon v-else dark> mdi-chevron-down </v-icon>
                    </v-btn>
                  </template>

                  <v-list>
                    <v-list-item @click="editItem(item)" class="operate-btn">
                      修改
                    </v-list-item>
                    <v-list-item @click="remove(item)" class="operate-btn">
                      删除
                    </v-list-item>
                    <v-list-item @click="setRoles(item)" class="operate-btn">
                      授权角色
                    </v-list-item>
                    <v-list-item
                      @click="setUserDatas(item)"
                      class="operate-btn"
                    >
                      设置机构
                    </v-list-item>
                  </v-list>
                </v-menu>
              </template>
              <template v-slot:no-data>
                <v-btn small color="primary" @click="dataInitialize()">
                  刷新
                </v-btn>
              </template>
            </v-data-table>
          </v-card-text>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "UserIndex",
  data: () => ({
    dense: false, //是否紧凑（降低行高）
    noDataText: "暂无任何数据", //没有数据时显示的内容
    loading: true, //开启加载条
    loadingText: "数据加载中...请稍候！", //加载条内容
    footerProps: {
      "items-per-page-options": [10, 20, 50, 100], //自定义每页行数的下拉框  -1 代表全部
      "items-per-page-text": "每页行数",
      //"items-per-page-all-text": "全部",
    },
    multiSort: true, //多列排序
    records: [], //数据
    total: 0, //数据总条数
    showExpand: true, //会在每个默认行上渲染一个展开图标
    singleExpand: true, //能同时展开多行还是只能展开一行
    showSelect: true, //将在默认表头中渲染一个复选框以切换所有行是否被选择，同时也为每个默认行渲染一个复选
    singleSelect: false, //指定能同时选择多行还是只能选择一行
    expanded: [], //展开行的内容

    //日期时间组件相关
    dateModal: false,
    itemKey: "id", //行项需要一个唯一的键属性才能展开。 默认值是id，但是你可以使用item-key prop来指定一个不同的item属性。
    tableTitle: "用户列表",
    //查询条件
    search: {
      orgId: [],
      account: "",
      nickName: "",
      birthday: [],
    },
    options: {
      page: 1, //当前页码
      itemsPerPage: 10, //每页多少条
      pageStart: 1, //起始页码
      pageStop: 1, //终止页码
      sortBy: ["id", "account"], //排序列
      sortDesc: [false, false], //排序列是否倒叙
    },
    headers: [
      {
        text: "序号", //标头
        align: "start", //所在位置
        sortable: false, //排序方式
        value: "id", //数据对应的字段名
      },
      { text: "账户", value: "account" },
      { text: "姓名", value: "name" },
      { text: "性别", sortable: false, value: "sex" },
      { text: "手机号", value: "phone" },
      { text: "状态", sortable: false, value: "status" },
      { text: "", value: "data-table-expand" }, //可展开列
      { text: "操作", value: "actions", sortable: false },
    ],
    selectedTableItems: [], //选中的表格项
    // 表格弹框相关
    dialog: false,
    rolesDialog: false,
    userDataDialog: false,
    editedIndex: -1,
    editedItem: {
      id: 0,
      account: "",
      password: "",
      nickName: "",
      name: "",
      avatar: "",
      birthday: "",
      sex: 0,
      email: "",
      phone: "",
      tel: "",
      adminType: 0,
      status: 0,
      isDeleted: false,
    },
    defaultItem: {
      id: 0,
      account: "",
      password: "",
      nickName: "",
      name: "",
      avatar: "",
      birthday: "",
      sex: 0,
      email: "",
      phone: "",
      tel: "",
      adminType: 0,
      status: 0,
      isDeleted: false,
    },
    userRoleItem: {
      userId: 0,
      grantRoleIds: [],
    },
    defaultUserRoleItem: {
      userId: 0,
      grantRoleIds: [],
    },
    userDataItem: {
      userId: 0,
      grantOrgIds: [],
    },
    defaultUserDataItem: {
      userId: 0,
      grantOrgIds: [],
    },
    dataDicts: {
      statusDicts: [],
      roleDicts: [],
    },
    // 树形图相关
    orgTreeItems: [],
    userDataTreeItems: [],
    userDataOpenItems: [],
  }),
  created() {
    // 初始化属性数据
    this.getOrgTree();
    this.setDictDatas();
  },
  methods: {
    /**
     * 清空查询条件
     */
    clearChanged() {
      this.search.account = "";
      this.search.nickName = "";
      this.search.birthday = "";
    },
    /**
     * 数据初始化
     */
    dataInitialize() {
      var that = this;
      that.loading = true;
      that.request
        .post("/api/user/page", {
          page: that.options.page,
          itemsPerPage: that.options.itemsPerPage,
          sortBy: that.options.sortBy,
          sortDesc: that.options.sortDesc,
          // 查询条件
          orgId: this.search.orgId,
          account: this.search.account,
          nickName: this.search.nickName,
          birthday: this.search.birthday,
        })
        .then((res) => {
          that.records = res.data.records;
          that.total = res.data.total;
          that.loading = false;
        })
        .catch((error) => {
          console.log(error);
          that.loading = false;
        });
    },
    // 获取角色的数据
    getRoleSelector() {
      var that = this;
      that.request.get("/api/role/selector").then((res) => {
        that.dataDicts.roleDicts = res.data;
        this.getOwnRole();
      });
    },
    // 获取用户拥有的角色
    getOwnRole() {
      var that = this;
      that.request
        .get("/api/user/ownRole", { userId: that.userRoleItem.userId })
        .then((res) => {
          let arr = that.dataDicts.roleDicts.filter((item) => {
            return res.data.find((prop) => {
              return prop == item.id;
            });
          });
          that.userRoleItem.grantRoleIds = arr;
          // 这里获取当前角色的菜单
          this.rolesDialog = true;
        });
    },
    // 获取用户所在机构的树形数据
    getUserOrgTree() {
      var that = this;
      that.request.get("/api/org/tree").then((res) => {
        that.userDataTreeItems = res.data;
        // 这里获取当前角色的菜单
        this.userDataDialog = true;
      });
    },
    // 获取授权的数据Id
    getOwnData() {
      var that = this;
      that.request
        .get("/api/user/ownData", { userId: that.userDataItem.userId })
        .then((res) => {
          that.userDataItem.grantOrgIds = res.data;
          this.getUserOrgTree();
        });
    },
    /**
     * 数据删除
     */
    dataDelete(ids) {
      var that = this;
      that.request.post("/api/user/removeBatchByIds", ids).then((res) => {
        that.$dialog.notify.success("删除成功！", {
          timeout: 2000,
        });
        setTimeout(() => {
          that.dataInitialize();
        }, 2000);
      });
    },
    /**
     * 数据添加或修改
     */
    dataAddOrEdit(item) {
      var that = this;
      that.request.post("/api/user/addOrEdit", item).then((res) => {
        that.$dialog.notify.success("保存成功！", {
          timeout: 2000,
        });
        setTimeout(() => {
          that.dataInitialize();
        }, 2000);
      });
    },
    /**
     * 菜单数据添加或修改
     */
    userRolesEdit(item) {
      var that = this;
      var userRole = {
        userId: item.userId,
        grantRoleIds: [],
      };
      if (item.grantRoleIds != null && item.grantRoleIds.length > 0) {
        item.grantRoleIds.forEach((element) => {
          userRole.grantRoleIds.push(element.id);
        });
      }
      that.request.post("/api/user/grantRole", userRole).then((res) => {
        that.$dialog.notify.success("保存成功！", {
          timeout: 2000,
        });
      });
    },
    /**
     * 用户授权数据修改
     */
    userDataEdit(item) {
      var that = this;
      that.request.post("/api/user/grantData", item).then((res) => {
        that.$dialog.notify.success("保存成功！", {
          timeout: 2000,
        });
      });
    },
    /**
     * 状态过滤
     */
    statusFilter(status) {
      const values = this.dataDicts.statusDicts.filter(
        (item) => item.code == status
      );
      if (values.length > 0) {
        return values[0].value;
      }
    },
    /**
     * 设置字典数据
     */
    setDictDatas() {
      var that = this;
      that.request
        .get("/api/dictType/dropDown", {
          code: "common_status",
        })
        .then((res) => {
          that.dataDicts.statusDicts = res.data;
        });
    },
    // 获取机构的树形数据
    getOrgTree() {
      var that = this;
      that.request.get("/api/org/tree").then((res) => {
        that.orgTreeItems = res.data;
      });
    },
    treeOn(item) {
      this.search.orgId.push(item[0].id);
      this.dataInitialize();
    },
    /**
     * 删除项
     */
    remove(dataItem) {
      var that = this,
        ids = [];
      if (dataItem == -1) {
        // 批量删除
        var items = that.selectedTableItems;
        if (items == undefined || items == null || items.length == 0) {
          this.$dialog.notify.warning("请选择要删除的数据项！", {
            position: "top-right",
            timeout: 3000,
          });
          return;
        }
        ids = items.map((item) => {
          return item.id;
        });
      } else {
        ids.push(dataItem.id);
      }
      that.$dialog.confirm({
        text: "确定要删除该项数据吗?",
        title: "警告",
        icon: "mdi-alert-circle",
        actions: [
          {
            text: "取消",
            key: false,
          },
          {
            text: "确定",
            color: "primary",
            key: true,
            handler: function () {
              that.dataDelete(ids);
            },
          },
        ],
      });
    },
    /**
     * 修改项
     */
    editItem(item) {
      this.editedIndex = this.records.indexOf(item);
      this.editedItem = Object.assign({}, item);
      this.editedItem.sex = this.editedItem.sex.toString();
      this.dialog = true;
    },
    /**
     * 角色授权菜单
     */
    setRoles(item) {
      this.userRoleItem.userId = item.id;
      this.getRoleSelector();
    },
    /**
     * 角色授权菜单
     */
    setUserDatas(item) {
      this.userDataItem.userId = item.id;
      this.getOwnData();
    },
    /**
     * 关闭编辑弹框
     */
    close() {
      this.dialog = false;
      this.$nextTick(() => {
        this.editedItem = Object.assign({}, this.defaultItem);
        this.editedIndex = -1;
      });
    },
    /**
     * 保存
     */
    save() {
      if (this.$refs.form.validate()) {
        if (this.editedIndex > -1) {
          //修改的逻辑
          this.dataAddOrEdit(this.editedItem);
        } else {
          //添加的逻辑
          this.dataAddOrEdit(this.editedItem);
        }
        this.close();
      }
    },
    /**
     * 关闭编辑弹框
     */
    rolesClose() {
      this.rolesDialog = false;
      this.$nextTick(() => {
        this.userRoleItem = Object.assign({}, this.defaultUserRoleItem);
      });
    },
    /**
     * 保存
     */
    rolesSave() {
      if (this.$refs.rolesForm.validate()) {
        this.userRolesEdit(this.userRoleItem);
        this.rolesClose();
      }
    },
    /**
     * 关闭编辑弹框
     */
    userDataClose() {
      this.userDataDialog = false;
      this.$nextTick(() => {
        this.userDataItem = Object.assign({}, this.defaultUserDataItem);
      });
    },
    /**
     * 保存
     */
    userDataSave() {
      if (this.$refs.userDataForm.validate()) {
        this.userDataEdit(this.userDataItem);
        this.userDataClose();
      }
    },
  },
  computed: {
    formTitle() {
      return this.editedIndex === -1 ? "添加" : "修改";
    },
  },
  watch: {
    dialog(val) {
      val || this.close();
    },
    rolesDialog(val) {
      val || this.close();
    },
  },
};
</script>